package com.shanghaionstar.discover.service;

import android.content.Context;

import com.onstar.cn.api.VehicleService;
import com.onstar.cn.common.exception.OnStarException;
import com.onstar.cn.common.util.Constants;
import com.onstar.cn.framework.annotation.http.HeadsValue;
import com.onstar.cn.framework.annotation.http.Request;
import com.onstar.cn.framework.mvp.base.core.BaseService;
import com.onstar.cn.framework.network.HttpInjectUtils;
import com.onstar.cn.framework.network.entity.RequestEntity;
import com.onstar.cn.framework.network.enumtype.HttpAccept;
import com.onstar.cn.framework.network.enumtype.HttpMethod;
import com.onstar.cn.framework.network.enumtype.Language;
import com.onstar.cn.framework.utils.GsonHelper;
import com.onstar.cn.mag.enumtype.RemoteCommandsType;
import com.onstar.cn.sqlite.entities.PollingEntity;
import com.onstar.cn.vehicle.entity.ErrorInfo;
import com.onstar.cn.vehicle.entity.RequestStatus;
import com.onstar.cn.vehicle.entity.VehicleCommand;
import com.onstar.cn.vehicle.entity.VehicleWifiInfo;
import com.shanghaionstar.discover.model.WifiInfoModel;
import com.shanghaionstar.service.VehicleManager;
import com.shanghaionstar.utils.ApplicationUtil;
import com.shanghaionstar.utils.BusinessUtil;
import com.shanghaionstar.utils.NetConnectUtil;

import org.json.JSONException;
import org.json.JSONObject;

import rx.Observable;
import rx.functions.Func0;

/**
 * Created by 7828wc on 16/7/27.
 */
public class WifiHomeService extends BaseService<WifiInfoModel> {
    private Context context;
    private VehicleManager manager;

    public WifiHomeService(Context context) {
        this.context = context;
        manager = new VehicleManager(context, Constants.CURRENT_SERVER_URL);
    }

    @Override
    public RequestEntity getRequestEntity() {
        return null;
    }

    @Override
    public WifiInfoModel jsonToBean(String json) {
        return null;
    }

    @Request(heads = @HeadsValue(accept = HttpAccept.JSON, language = Language.AUTO), method = HttpMethod.POST)
    public Observable<WifiInfoModel> getHotSpotInfo(final WifiInfoModel model) {
        return Observable.defer(new Func0<Observable<WifiInfoModel>>() {
            @Override
            public Observable<WifiInfoModel> call() {
                try {
                    final RemoteCommandsType remoteCommandType = model.getRemoteCommandType();
                    BusinessUtil.initPollingStatusBeforePolling(remoteCommandType, ApplicationUtil.getInstance().getVin(),manager);
                    VehicleService joinmeService = new VehicleService(Constants.CURRENT_SERVER_URL);
                    RequestEntity requestEntity = NetConnectUtil.getAuthRequestEntity(context);

                    String body = "";
                    if (remoteCommandType.equals(RemoteCommandsType.COMMAND_SETHOTSPOTINFO)) {
                        VehicleCommand command = new VehicleCommand();
                        VehicleWifiInfo wifiInfo = new VehicleWifiInfo();
                        wifiInfo.setPassphrase(model.getPassphrase());
                        wifiInfo.setSsid(model.getSsid());
                        command.setHotspotInfo(wifiInfo);
                        body = GsonHelper.toJson(command);
                    }

                    requestEntity = joinmeService.commondHotSpot(requestEntity, ApplicationUtil.getInstance().getVin(),remoteCommandType,body);
                    requestEntity = HttpInjectUtils.injectHttp(WifiHomeService.this.getClass(), "getHotSpotInfo", requestEntity, WifiInfoModel.class);
                    String json = BusinessUtil.getResponse(getDatas(requestEntity), context);

                    JSONObject error = GsonHelper.getJsonObject(json, "error");
                    JSONObject commandResponse = GsonHelper.getJsonObject(json, "commandResponse");
                    if (error != null) {
                        try {
                            String code = error.getString("code");
                            String description = error.getString("description");
                            ErrorInfo errorInfo = new ErrorInfo();
                            errorInfo.setCode(code);
                            errorInfo.setMsg(description);
                            BusinessUtil.updateToFailPollingStatusBeforePolling(remoteCommandType, ApplicationUtil.getInstance().getVin(),manager);
                            throw new OnStarException(errorInfo.getCode(), errorInfo.getMsg());
                        } catch (JSONException e) {
                            processError(remoteCommandType, e);
                        }
                    } else if (commandResponse != null) {
                        try {
                            if (RequestStatus.InProgress.getStringValue().equals(commandResponse.getString("status"))) {
                                String url = commandResponse.getString("url");
                                String requestId = url.substring(url.lastIndexOf("s") + 2, url.length());
                                model.setRequestId(requestId);
                                startPollVehicleStatus(remoteCommandType, requestId);
                            } else if (RequestStatus.Success.getStringValue().equals(commandResponse.getString("status"))) {

                            }
                        } catch (JSONException e) {
                            processError(remoteCommandType, e);
                        }
                    }

                    return Observable.just(model);
                } catch (OnStarException e) {
                    return Observable.error(e);
                }
            }
        });
    }

    public void startPollVehicleStatus(RemoteCommandsType commandsType, String requestId) {
        PollingEntity entity = new PollingEntity();
        entity.setVin(ApplicationUtil.getInstance().getVin());
        entity.setToken(ApplicationUtil.getInstance().getToken());
        entity.setRequestType(commandsType.value());
        entity.setRequestId(requestId);
        manager.startPoll(entity);
    }

    private void processError(final RemoteCommandsType commandType, Exception e) throws OnStarException {
        ErrorInfo errorInfo = BusinessUtil.getErrorInfoByException(context, e);
        BusinessUtil.updateToFailPollingStatusBeforePolling(commandType, ApplicationUtil.getInstance().getVin(),manager);
        throw new OnStarException(errorInfo.getCode(), errorInfo.getMsg());
    }

    public void stopPollingService(RemoteCommandsType remoteCommandType) {
        BusinessUtil.updateToFailPollingStatusBeforePolling(remoteCommandType, ApplicationUtil.getInstance().getVin(),manager);
    }
}
